# -*- coding: utf-8 -*-
# @Time: 2023/4/14 14:05
# @File: auth.py
# @Desc: 存放和用户相关的model

from exts import db
import shortuuid
from datetime import datetime
from werkzeug.security import generate_password_hash, check_password_hash
from sqlalchemy_serializer import SerializerMixin


# BBS论坛权限模型
class Permission(object):
    ALL_PERMISSIONS = 0b11111111  # 所有权限
    VISITORS = 0b00000001  # 访问者权限
    POSTERS = 0b00000010  # 帖子管理权限
    COMMETNERS = 0b00000100  # 评论管理权限
    BANNERS = 0b00001000  # 板块管理权限
    USERS = 0b00010000  # 用户管理权限
    STAFFERS = 0b00100000  # CMS后台管理权限


# BBS论坛角色模型
class Role(db.Model, SerializerMixin):
    serialize_only = ("id", "name", "desc", "create_date")
    __tablename__ = "role"
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(50), nullable=False)
    desc = db.Column(db.String(50), nullable=True)
    create_date = db.Column(db.DateTime, default=datetime.now)
    permissions = db.Column(db.Integer, default=Permission.VISITORS)


class User(db.Model, SerializerMixin):
    serialize_rules = ("-userpwd", "-posts", "-comments")  # 不序列化用户密码，
    # 需要注意的是这里需要使用元组（末尾加“,”）使用这种排除方式进行序列化，当模型中存在多表关联，会导致序列化死循环，
    # serialize_only = ("id", "email", "username", "avatar", "signature", "join_date", "is_active", "is_staff", "role")
    __tablename__ = "user"
    id = db.Column(db.String(255), primary_key=True, default=shortuuid.uuid)  # 用户ID
    email = db.Column(db.String(255), unique=True, nullable=False)  # 用户邮箱
    username = db.Column(db.String(255), nullable=False)  # 用户名
    userpwd = db.Column(db.String(255), nullable=False)  # 密码
    avatar = db.Column(db.String(255))  # 用户头像
    signature = db.Column(db.String(255))  # 个人签名
    join_date = db.Column(db.DateTime, default=datetime.now)
    is_active = db.Column(db.Boolean, default=True)  # 用户状态,用户是否可用(权限设定)
    is_staff = db.Column(db.Boolean, default=False)  # 是否为内部职员
    role_id = db.Column(db.Integer, db.ForeignKey("role.id"))  # 外键，角色表id
    role = db.relationship("Role", backref="users")

    def __init__(self, *args, **kwargs):
        if "password" in kwargs:
            self.password = kwargs.get("password")
            kwargs.pop("password")
        super(User, self).__init__(*args, **kwargs)

    @property
    def password(self):
        return self.userpwd

    @password.setter
    def password(self, newpassword):
        self.userpwd = generate_password_hash(newpassword)  # 密码加密

    def check_password(self, password):
        return check_password_hash(self.password, password)  # 检查密码

    def check_permission(self, permission):
        return (self.role.permissions & permission) == permission
